"""
HTML 转 PDF 服务模块
"""
import logging
import os
import tempfile
import uuid
from datetime import datetime

from src.html_to_pdf import html_to_pdf_async
from .utils import OSSManager


class HtmlToPdfService:
    """HTML 转 PDF 服务类"""

    def __init__(self, oss_manager: OSSManager):
        self.oss_manager = oss_manager
        self.temp_dir = tempfile.mkdtemp()
        self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")

    async def download_html_from_oss(self, oss_url):
        """从阿里云 OSS 下载 HTML 文件"""
        try:
            # 从 OSS URL 提取对象键
            if oss_url.startswith('http'):
                # 如果是完整的 OSS URL，提取对象键
                from urllib.parse import urlparse
                import requests

                parsed_url = urlparse(oss_url)
                # 移除开头的 '/' 并忽略查询参数
                object_key = parsed_url.path.lstrip('/')

                self.logger.info(f"解析URL: {oss_url}")
                self.logger.info(f"提取的对象键: {object_key}")

                # 生成临时文件名
                temp_filename = os.path.join(self.temp_dir, f"{uuid.uuid4().hex}.html")

                # 如果URL包含查询参数（签名URL），直接通过HTTP下载
                if parsed_url.query:
                    self.logger.info("检测到签名URL，使用HTTP方式下载...")
                    response = requests.get(oss_url, timeout=30)
                    response.raise_for_status()

                    # 确保使用正确的编码，先尝试UTF-8
                    response.encoding = 'utf-8'
                    html_content = response.text

                    # 如果UTF-8解码失败，尝试其他常见编码
                    if '�' in html_content or not html_content:
                        try:
                            html_content = response.content.decode('utf-8')
                        except UnicodeDecodeError:
                            try:
                                html_content = response.content.decode('gbk')
                            except UnicodeDecodeError:
                                html_content = response.content.decode('gb2312')

                    with open(temp_filename, 'w', encoding='utf-8') as f:
                        f.write(html_content)
                    self.logger.info(f"通过HTTP下载HTML文件到: {temp_filename}")
                else:
                    # 普通OSS路径，使用OSS SDK下载
                    self.logger.info("使用OSS SDK下载文件...")

                    # 先下载为二进制内容，然后正确解码
                    result = self.oss_manager.bucket.get_object(object_key)
                    content_bytes = result.read()

                    # 尝试不同的编码方式解码
                    html_content = None
                    for encoding in ['utf-8', 'gbk', 'gb2312']:
                        try:
                            html_content = content_bytes.decode(encoding)
                            self.logger.info(f"成功使用 {encoding} 编码解码HTML内容")
                            break
                        except UnicodeDecodeError:
                            continue

                    if html_content is None:
                        raise Exception("无法解码HTML内容，尝试了多种编码方式")

                    # 保存为UTF-8编码的文件
                    with open(temp_filename, 'w', encoding='utf-8') as f:
                        f.write(html_content)
                    self.logger.info(f"通过OSS SDK下载HTML文件到: {temp_filename}")

            else:
                # 如果已经是对象键，使用OSS SDK下载
                object_key = oss_url
                temp_filename = os.path.join(self.temp_dir, f"{uuid.uuid4().hex}.html")

                self.logger.info(f"正在从 OSS 下载文件: {object_key}")

                # 先下载为二进制内容，然后正确解码
                result = self.oss_manager.bucket.get_object(object_key)
                content_bytes = result.read()

                # 尝试不同的编码方式解码
                html_content = None
                for encoding in ['utf-8', 'gbk', 'gb2312']:
                    try:
                        html_content = content_bytes.decode(encoding)
                        self.logger.info(f"成功使用 {encoding} 编码解码HTML内容")
                        break
                    except UnicodeDecodeError:
                        continue

                if html_content is None:
                    raise Exception("无法解码HTML内容，尝试了多种编码方式")

                # 保存为UTF-8编码的文件
                with open(temp_filename, 'w', encoding='utf-8') as f:
                    f.write(html_content)
                self.logger.info(f"HTML 文件已下载到: {temp_filename}")

            return temp_filename, object_key

        except Exception as e:
            self.logger.error(f"从 OSS 下载 HTML 文件失败: {str(e)}")
            raise Exception(f"从 OSS 下载 HTML 文件失败: {str(e)}")

    async def upload_pdf_to_oss(self, pdf_file_path, original_object_key):
        """上传 PDF 文件到阿里云 OSS"""
        try:
            # 生成 PDF 的对象键
            base_name = os.path.splitext(original_object_key)[0]
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            pdf_object_key = f"{base_name}_{timestamp}.pdf"

            self.logger.info(f"正在上传 PDF 到 OSS: {pdf_object_key}")

            # 上传到 OSS
            with open(pdf_file_path, 'rb') as f:
                self.oss_manager.bucket.put_object(pdf_object_key, f)

            # 生成预签名下载链接 (有效期30天)
            expire_time = 30 * 24 * 60 * 60  # 1年的秒数
            pdf_url = self.oss_manager.bucket.sign_url('GET', pdf_object_key, expire_time)

            self.logger.info(f"PDF 文件已上传，预签名URL: {pdf_url}")
            return pdf_url, pdf_object_key

        except Exception as e:
            self.logger.error(f"上传 PDF 文件到 OSS 失败: {str(e)}")
            raise Exception(f"上传 PDF 文件到 OSS 失败: {str(e)}")

    async def convert_html_to_pdf(self, html_file_path):
        """将 HTML 文件转换为 PDF"""
        try:
            # 生成 PDF 文件路径
            pdf_file_path = os.path.join(self.temp_dir, f"{uuid.uuid4().hex}.pdf")

            self.logger.info(f"正在转换 HTML 到 PDF: {html_file_path} -> {pdf_file_path}")

            # 使用现有的转换函数
            success = await html_to_pdf_async(html_file_path, pdf_file_path)

            if not success:
                raise Exception("HTML 转 PDF 失败")

            self.logger.info(f"PDF 文件已生成: {pdf_file_path}")
            return pdf_file_path

        except Exception as e:
            self.logger.error(f"HTML 转 PDF 失败: {str(e)}")
            raise Exception(f"HTML 转 PDF 失败: {str(e)}")

    def cleanup_temp_files(self, *file_paths):
        """清理临时文件"""
        for file_path in file_paths:
            try:
                if file_path and os.path.exists(file_path):
                    os.remove(file_path)
                    self.logger.info(f"已删除临时文件: {file_path}")
            except Exception as e:
                self.logger.warning(f"删除临时文件失败 {file_path}: {str(e)}")
